package org.corey.wyp.business;

import java.sql.SQLException;
import java.util.List;

import org.corey.wyp.vo.AccountItem;
import org.corey.wyp.vo.Calendar;
import org.corey.wyp.vo.DaySettingTemplate;
import org.corey.wyp.vo.Month;
import org.corey.wyp.vo.MonthSetting;
import org.corey.wyp.vo.MonthSettingTemplate;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public class ProperityManager {
	private HibernateTemplate template;

	public void setSessionFactory(SessionFactory sf) {
		template = new HibernateTemplate(sf);
	}

	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Calendar> getCalendars() {
		List<Calendar> list = template.find("from Calendar");
		return list;
	}

	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public Calendar getCalendarAccount(final int year, final int month,
			final int date) {
		return (Calendar) template.execute(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria criteria = session.createCriteria(Calendar.class);
				criteria.add(Restrictions.eq("year", year));
				criteria.add(Restrictions.eq("month", month));
				criteria.add(Restrictions.eq("date", date));
				return criteria.list().size() > 0 ? criteria.list().get(0)
						: null;
			}
		});
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public boolean saveCalendar(Calendar calendar) {
		try {
			template.save(calendar);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean removeCalendar(Integer id) {
		Calendar c = new Calendar();
		c.setId(id);
		template.delete(c);
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public Integer saveAccountItem(AccountItem accountItem) {
		System.out.println("save Account Item");
		template.saveOrUpdate(accountItem);
		return accountItem.getId();
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean removeAccountItem(List<Integer> ids) {
		for (Integer i = 0; i < ids.size(); i++) {
			AccountItem item = (AccountItem) template.get(AccountItem.class,
					ids.get(i));
			template.delete(item);
		}
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean saveMonthSetting(MonthSetting monthSetting) {
		template.save(monthSetting);
		return true;
	}

	@SuppressWarnings("unchecked")
	public MonthSetting getMonthSetting(int year, int month) {
		List<MonthSetting> list = template
				.find("from MonthSetting m where m.year=" + year
						+ " and m.month=" + month);
		if (list == null || list.size() == 0) {
			return null;
		} else {
			return list.get(0);
		}
	}

	/******************************** SettingTemplate operation *********************/
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean removeDaySettingTemplate(Integer settingId) {
		DaySettingTemplate setting = new DaySettingTemplate();
		setting.setId(settingId);
		template.delete(setting);
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean removeMonthSettingTemplate(Integer settingId) {
		MonthSettingTemplate setting = new MonthSettingTemplate();
		setting.setId(settingId);
		template.delete(setting);
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean saveDaySettingTemplate(DaySettingTemplate daySettingTemplate) {
		template.save(daySettingTemplate);
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean saveMonthSettingTemplate(
			MonthSettingTemplate monthSettingTemplate) {
		template.save(monthSettingTemplate);
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean updateDaySettingTemplate(
			DaySettingTemplate daySettingTemplate) {
		template.update(daySettingTemplate);
		return true;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean updateMonthSettingTemplate(
			MonthSettingTemplate monthSettingTemplate) {
		template.update(monthSettingTemplate);
		return true;
	}

	/******************************** SettingTemplate operation *********************/
	public String testConnection(String seedString) {
		return "server response:" + seedString;
	}

	public Calendar getServerTime() {
		System.out.println("server:getServerTime");
		Calendar today = new Calendar();
		java.util.Calendar c = java.util.Calendar.getInstance();
		int year = c.get(java.util.Calendar.YEAR);
		int month = c.get(java.util.Calendar.MONTH);
		int date = c.get(java.util.Calendar.DATE);
		if ((today = this.getCalendarAccount(year, month, date)) == null) {
			today = new Calendar();
			today.setYear(year);
			today.setMonth(month);
			today.setDate(date);
			this.saveCalendar(today);
		}
		return today;
	}

	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.REQUIRED,readOnly=true)
	public Month getMonth(final int year, final int month) {
		List<Calendar> calendars = (List<Calendar>) template
				.execute(new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Criteria criteria = session
								.createCriteria(Calendar.class);
						criteria.add(Restrictions.eq("year", year));
						criteria.add(Restrictions.eq("month", month));
						return criteria.list().size() > 0 ? criteria.list()
								.get(0) : null;
					}
				});

		Month m = new Month();
		m.setYear(year);
		m.setMonth(month);
		m.setDays(calendars);
		return m;
	}
}
